using UnityEngine;
using Spine;
using Spine.Unity;
using Spine.Unity.AttachmentTools;


namespace Gameplay.Module
{
    public class SpineComponent : MonoBehaviour
    {
        private SkeletonAnimation _skeletonAnimation;

        private string _weaponSlotName = "weapon_right"; // 武器插槽的名称

        public Texture2D t2;

        private void Start()
        {
            _skeletonAnimation = GetComponent<SkeletonAnimation>();
            var skeleton = _skeletonAnimation.Skeleton;
            Slot slot = skeleton.FindSlot(_weaponSlotName);
            Material m = CreateRegionAttachmentByTexture(slot, t2);
        }

        private void ChangeWeapon()
        {
            SpineAtlasAsset asset = Resources.Load<SpineAtlasAsset>("Atlas/1_Atlas");
            Atlas atlas = asset.GetAtlas();

            AtlasRegion region = atlas.FindRegion("weapon1");

            RegionAttachment att = region.ToRegionAttachment(region.name);

            _skeletonAnimation.Skeleton.FindSlot(_weaponSlotName).Attachment = att;
        }

        /// <summary>
        /// Creates the region attachment by texture.
        /// </summary>
        /// <returns>The region attachment by texture.</returns>
        /// <param name="slot">Slot.</param>
        /// <param name="texture">Texture.</param>
        public Material CreateRegionAttachmentByTexture(Spine.Slot slot, Texture2D texture)
        {
            if (slot == null) return null;

            Spine.RegionAttachment oldAtt = slot.Attachment as Spine.RegionAttachment;
            if (oldAtt == null || texture == null) return null;

            oldAtt.RendererObject = CreateRegion(texture);
            oldAtt.SetUVs(0f, 1f, 1f, 0f, false);

            Material mat = new Material(Shader.Find("Sprites/Default"));
            mat.mainTexture = texture;
            AtlasPage page = (oldAtt.RendererObject as Spine.AtlasRegion).page;
            page.rendererObject = mat;

            slot.Attachment = oldAtt;
            return mat;
        }

        /// <summary>
        /// Creates the mesh attachment by texture.
        /// </summary>
        /// <returns>The mesh attachment by texture.</returns>
        /// <param name="slot">Slot.</param>
        /// <param name="texture">Texture.</param>
        public Material CreateMeshAttachmentByTexture(Spine.Slot slot, Texture2D texture)
        {
            if (slot == null) return null;
            Spine.MeshAttachment oldAtt = slot.Attachment as Spine.MeshAttachment;
            if (oldAtt == null || texture == null) return null;

            Spine.MeshAttachment att = new Spine.MeshAttachment(oldAtt.Name);
            att.RendererObject = CreateRegion(texture);
            att.Path = oldAtt.Path;

            att.Bones = oldAtt.Bones;
            att.Edges = oldAtt.Edges;
            att.Triangles = oldAtt.Triangles;
            att.Vertices = oldAtt.Vertices;
            att.WorldVerticesLength = oldAtt.WorldVerticesLength;
            att.HullLength = oldAtt.HullLength;
            att.RegionRotate = false;

            att.RegionU = 0f;
            att.RegionV = 1f;
            att.RegionU2 = 1f;
            att.RegionV2 = 0f;
            att.RegionUVs = oldAtt.RegionUVs;

            att.UpdateUVs();

            Material mat = new Material(Shader.Find("Sprites/Default"));
            mat.mainTexture = texture;
            (att.RendererObject as Spine.AtlasRegion).page.rendererObject = mat;

            slot.Attachment = att;
            return mat;
        }

        private Spine.AtlasRegion CreateRegion(Texture2D texture)
        {

            Spine.AtlasRegion region = new Spine.AtlasRegion();
            region.width = texture.width;
            region.height = texture.height;
            region.originalWidth = texture.width;
            region.originalHeight = texture.height;
            region.rotate = false;
            region.page = new Spine.AtlasPage();
            region.page.name = texture.name;
            region.page.width = texture.width;
            region.page.height = texture.height;
            region.page.uWrap = Spine.TextureWrap.ClampToEdge;
            region.page.vWrap = Spine.TextureWrap.ClampToEdge;

            return region;
        }

        private void RefreshSkeletonAttachments()
        {
            _skeletonAnimation.Skeleton.SetSlotsToSetupPose();
            _skeletonAnimation.AnimationState.Apply(_skeletonAnimation.Skeleton); //skeletonAnimation.Update(0);
        }

        
    }
}